#include"store_report.h"

tcp_server *server;


// 设置一个队列来存储数据
thread_queue<lars::ReportStatusRequest> **reportQueues = NULL;

int thread_cnt;

// 当客户端有上报host调用状态信息过来则调用函数进行存储
void get_report_status(const char *data, uint32_t len, int msgid, net_connection* net_conn, void *args){
    lars::ReportStatusRequest request;
    // 解析消息数据
    request.ParseFromArray(data, len);

    // 将解析出的数据存到mysql数据库中
    // Store_Report sr;
    // sr.store(request);

    // 将当前的请求入库， 轮询交给其中的一个线程处理
    static int index = 0;
    reportQueues[index]->send(request);
    index++;
    index = index % thread_cnt;


}


void create_reportdb_threads(void *args=NULL){
    // 加载配置文件
    thread_cnt = config_file::instance()->GetNumber("reporter", "db_thread_cnt", 5);
    printf("thread_cnt:[%d]\n", thread_cnt);
    // 开启线程消息队列
    reportQueues = new thread_queue<lars::ReportStatusRequest>* [thread_cnt]; 
    if(reportQueues == NULL){
        fprintf(stderr, "create thread_queue<lars::ReportStatusRequest>*[%d], error\n", thread_cnt);
        exit(1);
    }

    for(int i=0; i<thread_cnt; i++){
        // 给每个线程队列开辟空间
        reportQueues[i] = new thread_queue<lars::ReportStatusRequest>;
        if(reportQueues[i] == NULL){
            fprintf(stderr, "new thread_queue<lars::ReportStatusRequest>:[%d]", i);
            exit(1);
        }

        pthread_t tid;
        int ret = pthread_create(&tid, NULL, store_main, reportQueues[i]);
        if(ret != 0){
            perror("pthread_create error\n");
            exit(1);
        }
        // 设置线程分离
        pthread_detach(tid);
    }

}


int main(int argc, char** argv){
    event_loop loop;

    // 加载配置文件
    config_file::setPath("./conf/reporter.conf");
    std::string ip = config_file::instance()->GetString("reactor", "ip", "0.0.0.0");
    short port = config_file::instance()->GetNumber("reactor", "port", 8888);
    printf("ip: %s\tport: %d\n", ip.c_str(), port);

    // 允许连接的最大数
    int maxConn = config_file::instance()->GetNumber("reactor", "maxConn", 100);
    // 线程池个数，建议配置个数和CPU个数一致
    int thread_cnt = config_file::instance()->GetNumber("reactor", "threadNum", 3);  
    printf("maxConn: %d\tthread_cnt: %d\n", maxConn, thread_cnt);
    
    //创建套接字
    server = new tcp_server(&loop, ip.c_str(), port, maxConn, thread_cnt);

    // 添加上报请求的处理函数
    server->add_msg_router(lars::ID_ReportStatusRequest, get_report_status);

    // 为了防止IO操作而使业务出现延迟导致网络请求无法及时响应
    // 启动一个线程池，针对磁盘IO进行入库操作
    create_reportdb_threads();


    // 进入循环开始监听
    loop.event_process();
    
    return 0;
}